Avage võimas API arendus FastAPI ja Pydantic'uga. Õppige rakendama võimsat, automaatset päringu valideerimist, käsitlema vigu ja ehitama skaleeritavaid rakendusi.
FastAPI päringu valideerimise valdamine Pydantic mudelitega: põhjalik juhend
Kaasaegse veebiarenduse maailmas on tugevate ja usaldusväärsete API-de ehitamine ülimalt tähtis. Selle tugevuse kriitiline komponent on andmete valideerimine. Ilma selleta olete vastuvõtlik vanale põhimõttele "Sodi sisse, sodi välja", mis viib vigadeni, turvaaukudeni ja API tarbijate jaoks kehva arendajakogemuseni. Siin paistabki FastAPI ja Pydantic'i võimas kombinatsioon, muutes selle, mis oli varem tüütu ülesanne, elegantseks ja automatiseeritud protsessiks.
FastAPI, suure jõudlusega Pythoni veebiraamistik, on saavutanud tohutu populaarsuse oma kiiruse, lihtsuse ja arendajasõbralike funktsioonide poolest. Selle maagia südames on sügav integratsioon Pydantic'uga, andmete valideerimise ja seadete haldamise teegiga. Koos pakuvad nad sujuvat, tüübikindlat ja isedokumenteerivat viisi API-de ehitamiseks.
See põhjalik juhend viib teid sügavale sukeldumisele Pydantic'i mudelite kasutamisse päringu valideerimiseks FastAPI-s. Olenemata sellest, kas olete algaja, kes alles alustab API-dega, või kogenud arendaja, kes soovib oma töövoogu sujuvamaks muuta, leiate praktilisi teadmisi ja praktilisi näiteid selle olulise oskuse valdamiseks.
Miks on päringu valideerimine kaasaegsete API-de jaoks ülioluline?
Enne kui me koodi juurde hüppame, tehkem selgeks, miks sisendi valideerimine pole lihtsalt "hea-omada" funktsioon – see on põhiline vajadus. Nõuetekohane päringu valideerimine täidab mitmeid kriitilisi funktsioone:
- Andmete terviklikkus: See tagab, et teie süsteemi sisenevad andmed vastavad oodatavale struktuurile, tüüpidele ja piirangutele. See hoiab ära valesti vormistatud andmete teie andmebaasi rikkumise või ootamatu rakenduse käitumise põhjustamise.
- Turvalisus: Valideerides ja puhastades kõik sissetulevad andmed, loote esimese kaitseliini tavaliste turvaohtude, nagu NoSQL/SQL süstimise, Cross-Site Scripting (XSS) ja muude koormuspõhiste rünnakute vastu.
- Arendajakogemus (DX): API tarbijatele (sealhulgas teie enda frontend-tiimidele) on selge ja kohene tagasiside kehtetute päringute kohta hindamatu. Üldise 500 serverivea asemel tagastab hästi valideeritud API täpse 422 vea, kirjeldades täpselt, millised väljad on valed ja miks.
- Tugevus ja usaldusväärsus: Andmete valideerimine teie rakenduse sisenemispunktis hoiab ära kehtetute andmete levimise sügavale teie äriloogikasse. See vähendab oluliselt käitusajal tekkivate vigade tõenäosust ja muudab teie koodibaasi prognoositavamaks ja hõlpsamini silutavaks.
Võimupaar: FastAPI ja Pydantic
FastAPI ja Pydantic'i sünergia muudab raamistiku nii köitvaks. Lagundame nende rollid:
- FastAPI: Kaasaegne veebiraamistik, mis kasutab standardseid Pythoni tüübihinnanguid API parameetrite ja päringukeha määratlemiseks. See on ehitatud Starlette'ile suure jõudluse ja ASGI-le asünkroonsete võimaluste jaoks.
- Pydantic: Teek, mis kasutab neid samu Pythoni tüübihinnanguid andmete valideerimiseks, serialiseerimiseks (andmete teisendamine vormingutesse, nagu JSON ja sealt tagasi) ja seadete haldamiseks. Te määratlete oma andmete "kuju" klassina, mis pärib Pydantic'i `BaseModel`-i.
Kui kasutate Pydantic'i mudelit päringukeha deklareerimiseks FastAPI teekonnaoperatsioonis, orkestreerib raamistik automaatselt järgmist:
- See loeb sissetuleva JSON päringukeha.
- See parsib JSON-i ja edastab andmed teie Pydantic'i mudelile.
- Pydantic valideerib andmed teie mudelis määratletud tüüpide ja piirangute suhtes.
- Kui see on kehtiv, loob see teie mudeli eksemplari, andes teile täielikult tüübitud Pythoni objekti, millega oma funktsioonis töötada, koos automaatse täiendamisega teie redaktoris.
- Kui see on kehtetu, pĂĽĂĽab FastAPI kinni Pydantic'i `ValidationError`-i ja tagastab automaatselt ĂĽksikasjaliku JSON-vastuse HTTP 422 Unprocessable Entity olekukoodiga.
- See genereerib automaatselt JSON-skeemi teie Pydantic'i mudelist, mida kasutatakse interaktiivse API dokumentatsiooni (Swagger UI ja ReDoc) toiteks.
See automatiseeritud töövoog kõrvaldab standardkoodi, vähendab vigu ja hoiab teie andmemääratlused, valideerimisreeglid ja dokumentatsiooni suurepäraselt sünkroonis.
Alustamine: päringukeha põhi valideerimine
Vaatame seda lihtsa näitega. Kujutage ette, et ehitame API-t e-kaubanduse platvormile ja vajame lõpp-punkti uue toote loomiseks.
Esmalt määratlege oma tooteteabe kuju Pydantic'i mudeli abil:
# main.py
from fastapi import FastAPI
from pydantic import BaseModel
from typing import Optional
# 1. Määratlege Pydantic'i mudel
class Item(BaseModel):
name: str
description: Optional[str] = None
price: float
tax: Optional[float] = None
app = FastAPI()
# 2. Kasutage mudelit teekonnaoperatsioonis
@app.post("/items/")
async def create_item(item: Item):
# Sel hetkel on 'item' valideeritud Pydantic'i mudeli eksemplar
item_dict = item.dict()
if item.tax:
price_with_tax = item.price + item.tax
item_dict.update({"price_with_tax": price_with_tax})
return item_dict
Mis siin toimub?
`create_item` funktsioonis oleme tüübihinnanguga määranud parameetri `item` oma Pydantic'i mudeliks, `Item`. See on signaal FastAPI-le valideerimise teostamiseks.
Kehtiv päring:
Kui klient saadab POST päringu aadressile `/items/` koos kehtiva JSON kehaosaga, näiteks nii:
{
"name": "Super Gadget",
"price": 59.99,
"tax": 5.40
}
FastAPI ja Pydantic valideerivad selle edukalt. Teie `create_item` funktsiooni sees on `item` klassi `Item` eksemplar. Saate selle andmetele juurde pääseda punktnotatsiooni abil (nt `item.name`, `item.price`) ja teie IDE pakub täielikku automaatset täiendamist. API tagastab 200 OK vastuse koos töödeldud andmetega.
Kehtetu päring:
Nüüd vaatame, mis juhtub, kui klient saadab valesti vormistatud päringu, näiteks saates hinna stringina ujukomaarvu asemel:
{
"name": "Faulty Gadget",
"price": "ninety-nine"
}
Te ei pea kirjutama ĂĽhtegi `if` lauset ega `try-except` plokki. FastAPI pĂĽĂĽab automaatselt Pydantic'i valideerimisvea ja tagastab selle kaunilt detailse HTTP 422 vastuse:
{
"detail": [
{
"loc": [
"body",
"price"
],
"msg": "value is not a valid float",
"type": "type_error.float"
}
]
}
See veateade on kliendi jaoks uskumatult kasulik. See ütleb neile vea täpse asukoha (`body` -> `price`), inimesele loetava teate ja masinloetava veatüübi. See on automaatse valideerimise jõud.
Pydantic'i täpsem valideerimine FastAPI-s
Põhiline tüübikontroll on alles algus. Pydantic pakub rikkalikku tööriistakomplekti keerukamate valideerimisreeglite jaoks, mis kõik integreeruvad sujuvalt FastAPI-ga.Välja piirangud ja valideerimine
Saate väljadele kehtestada spetsiifilisemaid piiranguid, kasutades Pydantic'i funktsiooni `Field` (või FastAPI `Query`, `Path`, `Body`, mis on `Field` alamklassid).
Loome kasutaja registreerimismudeli mõnede levinud valideerimisreeglitega:
from pydantic import BaseModel, Field, EmailStr
class UserRegistration(BaseModel):
username: str = Field(
...,
min_length=3,
max_length=50,
regex="^[a-zA-Z0-9_]+$"
)
email: EmailStr # Pydantic'il on sisseehitatud tĂĽĂĽbid tavaliste vormingute jaoks
password: str = Field(..., min_length=8)
age: Optional[int] = Field(
None,
gt=0,
le=120,
description="Vanus peab olema positiivne täisarv."
)
@app.post("/register/")
async def register_user(user: UserRegistration):
return {"message": f"Kasutaja {user.username} registreeriti edukalt!"}
Selles mudelis:
- `username` peab olema 3–50 tähemärki pikk ja võib sisaldada ainult tähtnumbrilisi tähemärke ja allkriipse.
- `email` valideeritakse automaatselt, et tagada selle kehtiv e-posti vorming, kasutades `EmailStr`-i.
- `password` peab olema vähemalt 8 tähemärki pikk.
- `age`, kui see on esitatud, peab olema suurem kui 0 (`gt`) ja väiksem või võrdne 120-ga (`le`).
- `...` (ellips) funktsiooni `Field` esimese argumendina näitab, et väli on kohustuslik.
Pesastatud mudelid
Reaalmaailma API-d tegelevad sageli keerukate, pesastatud JSON-objektidega. Pydantic käsitleb seda elegantselt, võimaldades teil manustada mudeleid teiste mudelite sisse.
from typing import List
class Tag(BaseModel):
id: int
name: str
class Article(BaseModel):
title: str
content: str
tags: List[Tag] = [] # Teiste Pydantic'i mudelite loend
author_id: int
@app.post("/articles/")
async def create_article(article: Article):
return article
Kui FastAPI saab selle lõpp-punkti taotluse, valideerib see kogu pesastatud struktuuri. See tagab, et `tags` on loend ja et iga element selles loendis on kehtiv `Tag` objekt (st sellel on täisarvuline `id` ja string `name`).
Kohandatud valideerijad
Äriloogika jaoks, mida ei saa standardsete piirangutega väljendada, pakub Pydantic `@validator` dekoraatori. See võimaldab teil kirjutada oma valideerimisfunktsioone.
Klassikaline näide on parooli välja kinnitamine:
from pydantic import BaseModel, Field, validator
class PasswordChangeRequest(BaseModel):
new_password: str = Field(..., min_length=8)
confirm_password: str
@validator('confirm_password')
def passwords_match(cls, v, values, **kwargs):
# 'v' on 'confirm_password' väärtus
# 'values' on juba töödeldud väljade sõnastik
if 'new_password' in values and v != values['new_password']:
raise ValueError('Paroolid ei ĂĽhti')
return v
@app.put("/user/password")
async def change_password(request: PasswordChangeRequest):
# Loogika parooli muutmiseks...
return {"message": "Parool on edukalt uuendatud"}
Kui valideerimine ebaõnnestub (st funktsioon tõstab `ValueError`), püüab Pydantic selle kinni ja FastAPI teisendab selle standardsesse 422 veavastuseks, nagu ka sisseehitatud valideerimisreeglite puhul.
Erinevate päringuosade valideerimine
Kuigi päringukehad on kõige levinum kasutusjuht, kasutab FastAPI samu valideerimispõhimõtteid ka HTTP päringu muude osade jaoks.
Tee- ja päringuparameetrid
Tee- ja päringuparameetritele saate lisada täpsema valideerimise, kasutades `fastapi` funktsioone `Path` ja `Query`. Need töötavad täpselt nagu Pydantic'i `Field`.
from fastapi import FastAPI, Path, Query
from typing import List
app = FastAPI()
@app.get("/search/")
async def search(
q: str = Query(..., min_length=3, max_length=50, description="Teie otsingupäring"),
tags: List[str] = Query([], description="Filtreerimiseks kasutatavad sildid")
):
return {"query": q, "tags": tags}
@app.get("/files/{file_id}")
async def get_file(
file_id: int = Path(..., gt=0, description="Hangitava faili ID")
):
return {"file_id": file_id}
Kui proovite pääseda juurde `/files/0`, tagastab FastAPI 422 vea, kuna `file_id` ei läbi valideerimist `gt=0` (suurem kui 0). Samamoodi ebaõnnestub taotlus aadressile `/search/?q=ab` piirangu `min_length=3` tõttu.
Valideerimisvigade graatsiline käsitlemine
FastAPI vaikimisi 422 veavastus on suurepärane, kuid mõnikord peate seda kohandama, et see sobiks konkreetse standardiga või lisaks täiendavat logimist. FastAPI muudab selle oma erandite käsitlemise süsteemiga lihtsaks.
Saate luua kohandatud erandite käsitleja `RequestValidationError` jaoks, mis on konkreetne eranditüüp, mille FastAPI tõstab Pydantic'i valideerimise ebaõnnestumisel.
from fastapi import FastAPI, Request, status
from fastapi.exceptions import RequestValidationError
from fastapi.responses import JSONResponse
app = FastAPI()
@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request: Request, exc: RequestValidationError):
# Saate siia veateabe logida
# print(exc.errors())
# print(exc.body)
# Kohandage vastusevormingut
custom_errors = []
for error in exc.errors():
custom_errors.append(
{
"field": ".".join(str(loc) for loc in error["loc"]),
"message": error["msg"],
"type": error["type"]
}
)
return JSONResponse(
status_code=status.HTTP_400_BAD_REQUEST,
content={"error": "Valideerimine ebaõnnestus", "details": custom_errors},
)
# Lisage lõpp-punkt, mis võib valideerimisel ebaõnnestuda
class Item(BaseModel):
name: str
price: float
@app.post("/items/")
async def create_item(item: Item):
return item
Selle käsitlejaga saab kehtetu taotlus nüüd 400 Bad Request vastuse koos teie kohandatud JSON-struktuuriga, andes teile täieliku kontrolli API-i avaldatava veavormingu üle.
Pydantic'i mudelite parimad praktikad FastAPI-s
Skaleeritavate ja hooldatavate rakenduste loomiseks kaaluge järgmisi parimaid tavasid:
- Hoidke mudelid DRY (Don't Repeat Yourself): Kasutage korduste vältimiseks mudelite pärimist. Looge ühiste väljadega basismudel, seejärel laiendage seda konkreetsete kasutusjuhtude jaoks, nagu loomine (mis võib jätta välja väljad `id` ja `created_at`) ja lugemine (mis sisaldab kõiki välju).
- Eraldage sisend- ja väljundmudelid: Andmed, mida sisendina vastu võtate (`POST`/`PUT`), erinevad sageli andmetest, mida tagastate (`GET`). Näiteks ei tohiks te kunagi API vastuses tagastada kasutaja parooli räsiväärtust. Kasutage oma teekonnaoperatsiooni dekoraatoris parameetrit `response_model`, et määratleda väljundi jaoks konkreetne Pydantic'i mudel, tagades, et tundlikke andmeid ei avalikustata kunagi kogemata.
- Kasutage konkreetseid andmetüüpe: Kasutage Pydantic'i rikkalikku spetsiaalsete tüüpide komplekti, nagu `EmailStr`, `HttpUrl`, `UUID`, `datetime` ja `date`. Need pakuvad sisseehitatud valideerimist tavaliste vormingute jaoks, muutes teie mudelid tugevamaks ja väljendusrikkamaks.
- Konfigureerige mudeleid klassiga `Config`: Pydantic'i mudeleid saab kohandada sisemise klassi `Config` kaudu. Andmebaasi integreerimise peamine seade on `from_attributes=True` (varem `orm_mode=True` Pydantic v1-s), mis võimaldab mudelit täita ORM-objektidest (nagu need, mis pärinevad SQLAlchemy-st või Tortoise ORM-ist), pääsedes juurde atribuutidele, mitte sõnastiku võtmetele.
Järeldus
Pydantic'i sujuv integreerimine on vaieldamatult üks FastAPI põhilisi funktsioone. See tõstab API arendust, automatiseerides andmete valideerimise, serialiseerimise ja dokumentatsiooni olulisi, kuid sageli tüütuid ülesandeid. Määratledes oma andmekujud üks kord Pydantic'i mudelitega, saate palju eeliseid: tugev turvalisus, täiustatud andmete terviklikkus, suurepärane arendajakogemus teie API tarbijatele ja hooldatavam koodibaas teile endale.Liigutades valideerimisloogika oma äriloogikast deklaratiivsetesse andmemudelitesse, loote API-d, mis pole mitte ainult kiired käivitumisel, vaid ka kiired ehitamisel, kergesti mõistetavad ja turvalised kasutada. Seega, kui alustate järgmist Python API projekti, kasutage tõeliselt professionaalsete teenuste loomiseks FastAPI ja Pydantic'i võimsust.